
local jass = require 'jass.common'
local japi = require 'jass.japi'
local dbg = require 'jass.debug'
local message = require 'jass.message'

local lightning = {}
setmetatable(lightning,lightning)
ac.lightning = lightning

--- 闪电默认表
lightning.default = {
    ['汲取']	 	= 	"DRAB",
	['闪电链主'] 	= 	"CLPB",
	['闪电链次'] 	= 	"CLSB",
	['生命汲取'] 	= 	"DRAL",
	['魔法汲取'] 	= 	"DRAM",
	['死亡之指'] 	= 	"AFOD",
	['叉状闪电'] 	= 	"FORK",
	['医疗波主'] 	= 	"HWPB",
	['医疗波次'] 	= 	"HWSB",
	['闪电攻击'] 	= 	"CHIM",
	['魔法镣铐'] 	= 	"LEAS",
	['法力燃烧'] 	= 	"MBUR",
	['魔力之焰'] 	= 	"MFPB",
	['灵魂锁链'] 	= 	"SPLK",
}


-- 创建闪电效果
function lightning.create(data)
    local ln = setmetatable(data,lightning)
    local id = lightning.default[ln.id] or ln.id
    ln._clock = ac.clock() / 1000
    if ln.fade > 0 then 
        ln.time = ln.fade 
    end
    local x1, y1, z1 = ln.from:get_impact_point():get()
    local x2, y2, z2 = ln.to:get_impact_point():get()
    z1 = z1 + ln.ozf 
    z2 = z2 + ln.ozt 
    ln.handle = jass.AddLightningEx(id, true, x1, y1, z1, x2, y2, z2)
    ln.gchash = ln.handle
    dbg.gchash(ln,ln.handle)
    lightning.group[ln] = true 
    return ln
end

-- 输出
function lightning:__tostring()
    return ("闪电效果[%d]"):format(self.handle)
end 

function lightning:__call(data)
    return lightning.create(data)
end


--- 模块初始化
function lightning.init()
    --- 存放所有闪电效果
    lightning.group = {}
    lightning.clock = ac.clock() / 1000
    ac.hardware:on("界面绘制")(function()
        for ln in pairs(lightning.group) do 
            if not ln.removed then 
                ln:update()
            end 
        end
    end)
end 

--- 更新所有闪电效果
function lightning.update()
    lightning.clock = ac.clock() / 1000
    for ln in pairs(lightning.group) do 
        if not ln.removed then 
            if ln.time > 0 then
                if (lightning.clock - ln._clock) >= ln.time then 
                    ln:remove()
                end
            end
            if ln.auto then 
                if ln.from.removed or ln.to.removed then 
                    ln:remove()
                end
            end 
        end 
    end 
end 


local mt = {}
lightning.__index = mt 

-- 结构类型
mt.type = 'lightning'

-- 句柄(伪)
mt.handle = jass.ConvertUnitState(0)

-- 闪电id
mt.id = '闪电链主'

-- 起始
mt.from = nil 

-- 终点
mt.to = nil 

-- 颜色 r
mt.red = 100

-- 颜色 g
mt.green = 100

-- 颜色 b
mt.blue = 100

-- 透明度 a
mt.alpha = 100

-- 起始高度偏移
mt.ozf = 0

-- 终点高度偏移
mt.ozt = 0

-- 持续时间(-1为无限)
mt.time = -1

-- 自动渐变
mt.fade = -1

-- 自动删除
mt.auto = true

-- 诞生节点
mt._clock = 0

-- 删除
function mt:remove()
    if self.removed then 
        return false 
    end 
    self.removed = true 
    lightning.group[self] = nil
	jass.DestroyLightning(self.handle)
    self.handle = nil 
end 

--- 执行事件
function mt:notify(name,...)
    if self.removed then
        return false
    end
    local func = self[name]
    if func then 
        return select(2, xpcall(func, runtime.error_handle, self, ...))
    end 
end 

-- 更新
function mt:update()
    if self.removed then 
        return false 
    end 
    local x1,y1,z1 = self.from:get_impact_point():get()
    local x2,y2,z2 = self.to:get_impact_point():get()
    z1 = z1 + self.ozf 
    z2 = z2 + self.ozt 
    jass.MoveLightningEx(self.handle, false, x1, y1, z1, x2, y2, z2)
    if self.fade > 0 then
        self:color(self.red,self.green,self.blue,(100 - (lightning.clock - self._clock) / self.fade * 100))
    end 
end 

-- 淡出
function mt:fadeout(time)
    if self.removed then 
        return 
    end 
    if time and time > 0 then 
        self._clock = ac.clock() / 1000
        self.fade = time
        self.time = time
        self.auto = true 
    end 
end

-- 设置颜色 
-- 0 params get r,g,b,a
-- 1 params change color by 0xffffffff
-- 4 params change color by r,g,b,a
function mt:color(...)
    local n = select('#',...)
    if n == 0 then 
        return self.red,self.green,self.blue,self.alpha
    end
    local args = {...}
    if n == 1 then
        self.red   = ((args[1] << 40) >> 56) / 255 * 100
        self.green = ((args[1] << 48) >> 56) / 255 * 100
        self.blue  = ((args[1] << 56) >> 56) / 255 * 100
        self.alpha = ((args[1] << 32) >> 56) / 255 * 100
    else
        self.red   = args[1] or self.red
        self.green = args[2] or self.green
        self.blue  = args[3] or self.blue
        self.alpha = args[4] or self.alpha
    end
    jass.SetLightningColor(self.handle, math.limit(self.red / 100,0,1), math.limit(self.green / 100,0,1), math.limit(self.blue / 100,0,1), math.limit(self.alpha / 100,0,1))
    return self
end 

return lightning
